package OS.experiment12;

import com.sun.javaws.util.JfxHelper;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ButtonListener implements ActionListener, Callback {

    //监听按钮功能
    public static int CREATE = 0;
    public static int BLOCK = 1;
    public static int WAKEUP = 2;
    public static int STOP = 3;
    public static int SHOW = 4;
    public static int SCHEDULE = 5;

    //按钮功能
    private int type;

    //进程操作实现，这可能不是好方法，但是很简单
    private static Process process = new Process();

    //当前正在显示的窗口
    private JFrame nowFrame;

    ButtonListener(int type){
        this.type = type;
        //不可在这里new Process，应该创建单例
        //this.process = new Process();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        switch (type){
            case 0:
                create();
                break;
            case 1:
                block();
                break;
            case 2:
                wakeup();
                break;
            case 3:
                stop();
                break;
            case 4:
                show();
                break;
            case 5:
                schedule0();
                break;
        }
    }

    @Override
    public void schedule() {
        if (null != nowFrame) nowFrame.setVisible(false);
    }

    private void create(){
        JFrame jFrame = new JFrame();
        jFrame.setTitle("创建进程");
        jFrame.setSize(300, 200);
        jFrame.setDefaultCloseOperation(3);
        jFrame.setLocationRelativeTo(null);
        GridLayout gridLayout = new GridLayout(5,1);
        jFrame.setLayout(gridLayout);

        JLabel nameLabel = new JLabel("请输入进程名称：");
        JTextField nameText=new JTextField();
        JLabel priorityLabel = new JLabel("请输入进程优先级：");
        JTextField priorityText=new JTextField();
        JButton jButton = new JButton("创建");

        jFrame.add(nameLabel);
        jFrame.add(nameText);
        jFrame.add(priorityLabel);
        jFrame.add(priorityText);
        jFrame.add(jButton);

        jFrame.setVisible(true);

        //设置当前显示的界面为jFrame
        nowFrame = jFrame;

        ButtonListener2 listener = new ButtonListener2(nameText, priorityText, ButtonListener2.CREATE_RESULT, process, this);
        jButton.addActionListener(listener);
    }

    /**
     * 阻塞、唤醒、停止界面基本相同抽出来公用
     * @param title     标题
     * @param button    按钮文字
     * @param type      窗口内容类型，就是是唤醒还是停止什么的
     */
    private void defaultFrame(String title, String button, int type){
        JFrame jFrame = new JFrame();
        jFrame.setTitle(title);
        jFrame.setSize(300, 200);
        jFrame.setDefaultCloseOperation(3);
        jFrame.setLocationRelativeTo(null);
        GridLayout gridLayout = new GridLayout(3,1);
        jFrame.setLayout(gridLayout);

        JLabel nameLabel = new JLabel("请输入进程名称：");
        JTextField nameText=new JTextField();
        JButton jButton = new JButton(button);

        jFrame.add(nameLabel);
        jFrame.add(nameText);
        jFrame.add(jButton);

        jFrame.setVisible(true);

        //设置当前显示的界面为jFrame
        nowFrame = jFrame;

        ButtonListener2 listener = new ButtonListener2(nameText, null, type, process, this);
        jButton.addActionListener(listener);
    }

    private void block(){
        defaultFrame("阻塞进程", "阻塞", ButtonListener2.BLOCK_RESULT);
    }

    private void wakeup(){
        defaultFrame("唤醒进程", "唤醒", ButtonListener2.WAKEUP_RESULT);
    }

    private void stop(){
        defaultFrame("停止进程", "停止", ButtonListener2.STOP_RESULT);
    }

    private void show(){
        JFrame jFrame = new JFrame();
        jFrame.setSize(1200, 500);
        jFrame.setDefaultCloseOperation(3);
        jFrame.setLocationRelativeTo(null);

        jFrame.setLayout(new BorderLayout());

        //主界面
        JPanel main = new JPanel();
        main.setLayout(new GridLayout(1, 3));

        //底部按钮
        JPanel buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1,1));

        //JPanel实现嵌套布局
        JPanel runningPanel = new JPanel();
        JPanel readyPanel = new JPanel();
        JPanel blockPanel = new JPanel();

        runningPanel.setLayout(new GridLayout(11,1));
        readyPanel.setLayout(new GridLayout(11,1));
        blockPanel.setLayout(new GridLayout(11,1));

        showProcessMain(runningPanel, readyPanel, blockPanel);

        //确定按钮
        JButton button = new JButton("确定");

        //添加到主界面
        main.add(runningPanel);
        main.add(readyPanel);
        main.add(blockPanel);

        //底部按钮界面
        buttonPanel.add(button);

        //添加到根布局
        jFrame.add(main, BorderLayout.CENTER);
        jFrame.add(buttonPanel, BorderLayout.SOUTH);

        //设置当前显示的界面为jFrame
        nowFrame = jFrame;

        ButtonListener2 listener = new ButtonListener2(null, null, ButtonListener2.SHOW_RESULT, process, this);
        button.addActionListener(listener);

        jFrame.setVisible(true);
    }

    /**
     * 重复使用抽出
     * @param runningPanel  .
     * @param readyPanel    .
     * @param blockPanel    .
     */
    private void showProcessMain(JPanel runningPanel, JPanel readyPanel, JPanel blockPanel){
        runningPanel.removeAll();
        readyPanel.removeAll();
        blockPanel.removeAll();

        runningPanel.repaint();
        readyPanel.repaint();
        blockPanel.repaint();

        //添加正在运行
        runningPanel.add(new JLabel("正在运行"));
        PCB running = process.getRunning();
        if (null == running){
            runningPanel.add(new JLabel("没有正在运行的进程"));
        }else {
            runningPanel.add(new JLabel(running.toString()));
        }

        //添加就绪
        readyPanel.add(new JLabel("就绪进程"));
        if (process.getReadyQueue().isEmpty()){
            readyPanel.add(new JLabel("没有就绪进程"));
        }
        for (PCB p : process.getReadyQueue().toArray(new PCB[0])){
            //详见Process#priorityScheduling()
            if(p.getState() == PCB.STATE_RUN) continue;
            readyPanel.add(new JLabel(p.toString()));
        }

        //添加阻塞
        blockPanel.add(new JLabel("阻塞进程"));
        if (process.getBlockQueue().isEmpty()){
            blockPanel.add(new JLabel("没有阻塞进程"));
        }
        for (PCB p : process.getBlockQueue().toArray(new PCB[0])){
            blockPanel.add(new JLabel(p.toString()));
        }

        runningPanel.revalidate();
        readyPanel.revalidate();
        blockPanel.revalidate();
    }

    private void schedule0(){
        JFrame jFrame = new JFrame();
        jFrame.setSize(1200, 500);
        jFrame.setDefaultCloseOperation(3);
        jFrame.setLocationRelativeTo(null);

        jFrame.setLayout(new BorderLayout());

        //顶部布局
        JPanel top = new JPanel();
        top.setLayout(new GridLayout(1,2));

        JButton timeRotationButton = new JButton("时间片轮转调度");
        JButton priorityScheduleButton = new JButton("优先级调度");

        top.add(timeRotationButton);
        top.add(priorityScheduleButton);

        //----------
        //主界面
        JPanel main = new JPanel();
        main.setLayout(new GridLayout(1, 3));

        //JPanel实现嵌套布局
        JPanel runningPanel = new JPanel();
        JPanel readyPanel = new JPanel();
        JPanel blockPanel = new JPanel();

        runningPanel.setLayout(new GridLayout(10,1));
        readyPanel.setLayout(new GridLayout(10,1));
        blockPanel.setLayout(new GridLayout(10,1));

        showProcessMain(runningPanel, readyPanel, blockPanel);

        main.add(runningPanel);
        main.add(readyPanel);
        main.add(blockPanel);

        //顶部按钮监听
        ButtonListener2 listener1 = new ButtonListener2(null, null, ButtonListener2.SCHEDULE_RESULT_1, process, new Callback() {
            @Override
            public void schedule() {
                main.removeAll();
                main.repaint();
                showProcessMain(runningPanel, readyPanel, blockPanel);
                main.add(runningPanel);
                main.add(readyPanel);
                main.add(blockPanel);
                main.revalidate();
            }
        });
        ButtonListener2 listener2 = new ButtonListener2(null, null, ButtonListener2.SCHEDULE_RESULT_2, process, new Callback() {
            @Override
            public void schedule() {
                showProcessMain(runningPanel, readyPanel, blockPanel);
                jFrame.validate();
            }
        });
        timeRotationButton.addActionListener(listener1);
        priorityScheduleButton.addActionListener(listener2);

        //----------
        //底部
        JPanel bottom = new JPanel();

        bottom.setLayout(new GridLayout(1,1));

        //确定按钮
        JButton button = new JButton("确定");
        bottom.add(button);

        ButtonListener2 listener = new ButtonListener2(null, null, ButtonListener2.SCHEDULE_RESULT, process, this);
        button.addActionListener(listener);

        jFrame.add(top, BorderLayout.NORTH);
        jFrame.add(main, BorderLayout.CENTER);
        jFrame.add(bottom, BorderLayout.SOUTH);

        nowFrame = jFrame;

        jFrame.setVisible(true);
    }
}
